package com.df.hotfix.scripts;

import com.df.hotfix.loader.HotFixLoader;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * 此脚本用来监听源代码的变化，动态编译，路径是写死的，可以改成配置的
 */
public class ScriptHotFixManager {
    private enum Single {
        INSTANCE;
        private ScriptHotFixManager scriptHotFixManager;

        Single() {
            scriptHotFixManager = new ScriptHotFixManager();
        }
    }

    Thread task;
    volatile boolean started = false;

    private ScriptHotFixManager() {
        task = new Thread(() -> {
            updateClass();
        });
    }

    public static ScriptHotFixManager instance() {
        return Single.INSTANCE.scriptHotFixManager;
    }

    Map<String, Long> modifyTimeCache = new HashMap<>();

    private void updateClass() {
        while (true) {
            if (!started) return;
//            System.out.println("变更检测");
            String checkPackage = "com.df.hotfix.scripts.impl";
            String checkPath = "D:\\MyProject\\bakend\\java\\my_test\\hotfix\\src\\main\\java\\com\\df\\hotfix\\scripts\\impl";
            File file = new File(checkPath);

            HotFixLoader loader = new HotFixLoader();
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File file1 : files) {
                    if (!file1.getName().endsWith(".java")) {
                        continue;
                    }
                    long lastModified = file1.lastModified();
                    String key = checkPackage + "." + file1.getName().replace(".java", "");
//                    System.out.println(key);
                    Long cacheTime = modifyTimeCache.get(key);
                    if (cacheTime == null) {
                        modifyTimeCache.put(key, lastModified);
                        continue;
                    }
                    if (!cacheTime.equals(lastModified)) {//有修改
                        try {
                            Class<?> result = loader.loadClass(key);
                            if(result==null){
                                continue;
                            }
                            if (IScript.class.isAssignableFrom(result)){
                                IScript instance = (IScript) result.newInstance();
                                ScriptManager.instance().replateScript(key,instance);
                                modifyTimeCache.put(key, lastModified);
                                System.out.println("update script:"+key);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void listenerStart() {
        if (started) return;
        synchronized (this) {
            if (started) return;
            task.start();
            started = true;
        }

    }

    public void lisenerStop() {
        started = false;
    }
}
